package cn.ywang.spring.framework.aop.framework;

import cn.ywang.spring.framework.aop.intercept.MethodInvocation;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
 * @author BeatificWang
 * @date 2019/5/4 16:07
 */
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {


	private AdvisedSupport advisedSupport;

	public JdkDynamicAopProxy(AdvisedSupport advisedSupport) {
		this.advisedSupport = advisedSupport;
	}

	@Override
	public Object getProxy() {
		return this.getProxy(this.advisedSupport.getTargetClass().getClassLoader());
	}

	@Override
	public Object getProxy(ClassLoader classLoader) {
		return Proxy.newProxyInstance(classLoader, this.advisedSupport.getTargetClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		List<Object> interceptorsAndDynamicMethodMatchers = this.advisedSupport.getInterceptorsAndDynamicInterceptionAdvice(method, this.advisedSupport.getTargetClass());
		MethodInvocation invocation = new MethodInvocation(proxy, this.advisedSupport.getTarget(), method, args, this.advisedSupport.getTargetClass(), interceptorsAndDynamicMethodMatchers);
		return invocation.proceed();
	}
}
